#ifndef DECODER_FUNCTIONS_H
#define DECODER_FUNCTIONS_H

#include "GF.h"
#include "gf_types.h"
#include "poly.h"

// Structures
// Input to power sums tower (pthread task to perform decode)
typedef struct {
   int	m;     	   
   int	t;            
   Matrix *add_one;
   Vector *r;	       // Word to decode
   Vector *S;	       // Pointer to Syndrome Vector Pointer
}  powerSumsParams;

// Input to sugiyama tower (pthread task to perform decode)
typedef struct {
   int m;
   int t;
   int correctFlag;    // 1 if inputted code word had no errors
   Matrix *add_one;
   Vector *S;	       // Pointer to syndrome vector (from previous tower)
   Vector *rts;        // Pointer to vectors for next stage of decode
   Vector *rts_inv;    
   Vector *r1;         
   Vector *t1;
}  sugiyamaParams;

// Input to correction tower (pthread task to perform decode)
typedef struct {
   int m;
   int correctFlag;    // 1 if inputted code word has no errors
   Matrix *add_one;
   Vector *rts;	       // Inputs from previous tower
   Vector *rts_inv;    
   Vector *r1; 
   Vector *t1;
   Vector *r;          // Word to decode
   Vector *T;          // Result of the decode
}  correctionParams;

// Input to control tower (pthread task to control decode pipeline)
typedef struct {
   int m;
   int t;
   int pipeDepth;				// Number of words to decode (array size)
   Matrix *add_one;			
   Vector** codeArray;			// Array of words to decode
   powerSumsParams *pParams;	// Input to power sums tower
   sugiyamaParams *sParams;		// Input to sugiyama tower
   correctionParams *cParams;	// Input to correction tower
   Vector **Result;				// Decoded word array
}  controlParams;

// Global Variables
pthread_mutex_t pStart, sStart, cStart;
int pBusy, sBusy, cBusy;
int pExit, sExit, cExit;

// Serial function declarations
int forney(int m, Matrix* add_one, Vector *Xinv, Vector *X, int kk, Vector *Om, Vector *Lam);
Vector * euclid(int m, Matrix *add_one, int t, Vector *r);

// Parallel function declarations
void* correctionTower(void *cParam);
void* sugiyamaTower(void *sParam);
void* powerSumsTower(void *pParam);
void* controlThread(void *parameters);
Vector** parallelTowers(int m, Matrix *add_one, int t,int pipeDepth, Vector** codeArray);

#endif
